﻿using System;

namespace LxCFD
{
    public class ConnectBase : ConnectHeadBase, IAMGSolvableContact, ISolvableContact
    {
        protected PairMatrix[] ADLUb;

        protected EquationBase O_Matrix;
        protected EquationBase N_Matrix;
        protected double[] O_x;
        protected double[] N_x;
        protected double[] O_ALUN;
        protected double[] N_ALUN;
        protected double[] O_ALUO;
        protected double[] N_ALUO;
        protected Vector3d[] O_grad;
        protected Vector3d[] N_grad;
        protected double[] O_xCommon;
        protected double[] N_xCommon;
        protected double[] O_bFaceCommon;
        protected double[] N_bFaceCommon;
        public override void CheckCreate(FvContact contact)
        {
            base.CheckCreate(contact);
            LxTool.CheckCreateArray(ref ADLUb, Pairs.Length);
        }
        public void SetArray(EquationBase OMatrix, EquationBase NMatrix)
        {
            this.O_Matrix = OMatrix;
            this.O_x = O_Matrix.x;
            this.O_ALUO = O_Matrix.ALUO;
            this.O_ALUN = O_Matrix.ALUN;
            this.O_grad = O_Matrix.Grad;
            this.O_xCommon = O_Matrix.x_Common;
            this.O_bFaceCommon = O_Matrix.b_FaceCommon;

            this.N_Matrix = NMatrix;
            this.N_x = N_Matrix.x;
            this.N_ALUO = N_Matrix.ALUO;
            this.N_ALUN = N_Matrix.ALUN;
            this.N_grad = N_Matrix.Grad;
            this.N_xCommon = N_Matrix.x_Common;
            this.N_bFaceCommon = N_Matrix.b_FaceCommon;

        }
        public void Copy_xCommonArray(int taskIndex)
        {
            CopyBound(O_xCommon, N_xCommon, taskIndex);
        }
        public void Copy_xArray(int taskIndex)
        {
            CopyBound(O_x, N_x, taskIndex);
        }
        protected void CopyBound(double[] OArray, double[] NArray, int taskIndex)
        {
            //{
            //    InnerIndex.FaceIDs.GetSeg(out int i1, out int endp1, taskIndex);
            //    for (; i1 < endp1; i1++)
            //    {
            //        ref FvPair pair = ref Pairs[i1];
            //        ref PairMatrix ab = ref ADLUb[i1];
            //        OArray[pair.O_Cell] = ab.a14 * NArray[pair.N_InnCell];
            //        NArray[pair.N_Cell] = ab.a41 * OArray[pair.O_InnCell];
            //    }
            //}
            {
                O_Index.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
                for (; i1 < endp1; i1++)
                {
                    double aluproduct = 0;
                    foreach (var pid in O_Cells[i1].OFaces)
                    {
                        aluproduct += ADLUb[pid].a14 * NArray[Pairs[pid].N_InnCell];
                    }
                    OArray[i1] = aluproduct;
                }
            }
            {
                N_Index.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
                for (; i1 < endp1; i1++)
                {
                    double aluproduct = 0;
                    foreach (var pid in N_Cells[i1].OFaces)
                    {
                        aluproduct += ADLUb[pid].a41 * OArray[Pairs[pid].O_InnCell];
                    }
                    NArray[i1] = aluproduct;
                }
            }
        }
        public void Restrict_ALU(out double ALUO, out double ALUN, ref MGPair mgPair)
        {
            double aluo = 0, alun = 0;
            foreach (var p in mgPair.FinePairs)
            {
                ref PairMatrix ab = ref ADLUb[p];
                aluo += ab.a14;
                alun += ab.a41;
            }
            ALUO = aluo;
            ALUN = alun;
        }
        public void Copy_yArray(int taskIndex)
        {
            CopyBound(Contact.O_BiCGSolver.y, Contact.N_BiCGSolver.y, taskIndex);
        }
        public void Copy_zArray(int taskIndex)
        {
            CopyBound(Contact.O_BiCGSolver.z, Contact.N_BiCGSolver.z, taskIndex);
        }
        public virtual void SetAb_Step1(int taskIndex)
        {
            throw new NotImplementedException();
        }

        public virtual void Update_x_Bound(int taskIndex)
        {
            throw new NotImplementedException();
        }
    }
}
